<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>俄罗斯方块</title>
    <style>
        body {
            border: 0px;
            margin: 0px;
            font-size: 14px;
            line-height: 14px;
        }

        .body {
            margin: auto;
            margin-top: 30px;
            width: 550px;
            height: 600px;
            background-color: antiquewhite;
        }

        .main {
            float: left;
            height: 600px;
            width: 400px;
            background-color: black;
            box-sizing: border-box;
            line-height: 0px;
        }

        .main .block {
            height: 40px;
            width: 40px;
            background-color: grey;
            box-sizing: border-box;
            border: 1px solid silver;
            display: inline-block;
            line-height: 40px;
            text-align: center;
            float: left;
        }

        .side {
            height: 600px;
            width: 150px;
            background-color: rgb(30, 124, 187);
            float: right;
            color: aqua;

        }

        .side .next {
            width: 100%;
            margin-top: 10px;
        }

        .side .next p {
            display: block;
            width: 100%;
            text-align: center;
        }

        .side .next .shape {
            height: 100px;
            width: 100px;
            background-color: black;
            margin: auto;
        }

        .side .speed {
            width: 100%;
            margin-top: 10px;
        }

        .side .speed p {
            display: block;
            width: 100%;
            text-align: center;
        }

        .side .speed .databox {
            height: 30px;
            width: 100px;
            background-color: black;
            margin: auto;
            line-height: 30px;
            text-align: center;
        }

        .side .score {
            width: 100%;
            margin-top: 10px;
        }

        .side .score p {
            display: block;
            width: 100%;
            text-align: center;

        }

        .side .score .databox {
            height: 30px;
            width: 100px;
            background-color: black;
            margin: auto;
            line-height: 30px;
            text-align: center;
        }

        .side .best {
            width: 100%;
            margin-top: 10px;
        }

        .side .best p {
            display: block;
            width: 100%;
            text-align: center;
        }

        .side .best .databox {
            height: 30px;
            width: 100px;
            background-color: black;
            margin: auto;
            line-height: 30px;
            text-align: center;
        }

        .side .btn {
            height: 30px;
            width: 100px;
            margin: auto;
            margin-top: 30px;
            text-align: center;
            font-size: 16px;
            color: rgb(179, 176, 176);
        }

        .side .btn:hover {
            cursor: pointer;
        }
    </style>
    <style>
        /* next */
        .shape>div {
            height: 100%;
            width: 100%;
            box-sizing: border-box;
        }

        .shape>div>div {
            height: 25px;
            width: 25px;
            float: left;
            box-sizing: border-box;
        }

        .flag {
            background-color: green;
            border: 1px rgb(25, 184, 104) solid;
        }

        .shape1 {
            padding: 12.5px 0;
        }

        .shape2 {
            padding: 25px 12.5px;
        }

        .shape3 {
            padding: 12.5px 25px;
        }

        .shape4 {
            padding: 25px 25px;
        }

        .shape5 {
            padding: 0 37.5px;
        }
    </style>
</head>

<body>
    <div class="body">
        <div class="main">
        </div>
        <div class="side">
            <div class="next">
                <p>NEXT</p>
                <div class="shape" id="next">
                    <div class="shape1" style="display: none">
                        <div></div>
                        <div class="flag"></div>
                        <div></div>
                        <div></div>
                        <div></div>
                        <div class="flag"></div>
                        <div class="flag"></div>
                        <div></div>
                        <div></div>
                        <div></div>
                        <div class="flag"></div>
                        <div></div>
                    </div>
                    <div class="shape2" style="display: none">
                        <div></div>
                        <div class="flag"></div>
                        <div></div>
                        <div class="flag"></div>
                        <div class="flag"></div>
                        <div class="flag"></div>
                    </div>
                    <div class="shape3" style="display: none">
                        <div class="flag"></div>
                        <div class="flag"></div>
                        <div></div>
                        <div class="flag"></div>
                        <div></div>
                        <div class="flag"></div>
                    </div>
                    <div class="shape4" style="display: none">
                        <div class="flag"></div>
                        <div class="flag"></div>
                        <div class="flag"></div>
                        <div class="flag"></div>
                    </div>
                    <div class="shape5" style="display: none">
                        <div class="flag"></div>
                        <div class="flag"></div>
                        <div class="flag"></div>
                        <div class="flag"></div>
                    </div>
                </div>
            </div>
            <div class="speed">
                <p>SPEED</p>
                <div class="databox">
                    1
                </div>
            </div>
            <div class="score">
                <p>SCORE</p>
                <div class="databox">
                    0
                </div>
            </div>
            <div class="best">
                <p>BEST</p>
                <div class="databox">
                    0
                </div>
            </div>
            <div class="btn" id="start">START</div>
        </div>
    </div>
</body>
<script>
    // 1            2              3            4 
    //     00             
    //     0000           0000       
    //       00         0000
    // 2          
    //       00         00                             00
    //     000000       0000           000000        0000
    //                  00               00            00
    // 3 
    //     0000              00          00          
    //       00          000000          00          000000  
    //       00                          0000        00
    // 4  
    //     0000
    //     0000
    // 5            
    //       00
    //       00
    //       00         00000000
    //       00
    function getBlocks() {
        let box = document.getElementsByClassName("main")[0];
        for (let i = 0; i < 15 * 10; i++) {
            box.innerHTML += `<div class="block"></div>`;
        }
        let list = box.getElementsByClassName("block");
        let blocks = [];
        for (let i = 0; i < 15; i++) {
            blocks[i] = [];
            for (let k = 0; k < 10; k++) {
                blocks[i][k] = list[i * 10 + k];
                blocks[i][k].flag = 0;
            }
        }
        return blocks;
    }
    function addSpeed() { }
    function getUnit(un) {
        let unit = [];
        switch (un) {
            case 1:
                unit = [
                    { x: 4, y: -3 },
                    { x: 4, y: -2 },
                    { x: 5, y: -2 },
                    { x: 5, y: -1 },
                ]
                break;
            case 2:
                unit = [
                    { x: 5, y: -2 },
                    { x: 4, y: -1 },
                    { x: 5, y: -1 },
                    { x: 6, y: -1 },
                ]
                break;
            case 3:
                unit = [
                    { x: 4, y: -3 },
                    { x: 5, y: -3 },
                    { x: 5, y: -2 },
                    { x: 5, y: -1 },
                ]
                break;
            case 4:

                unit = [
                    { x: 4, y: -1 },
                    { x: 4, y: -2 },
                    { x: 5, y: -1 },
                    { x: 5, y: -2 },
                ]
                break;
            case 5:
                unit = [
                    { x: 5, y: -4 },
                    { x: 5, y: -3 },
                    { x: 5, y: -2 },
                    { x: 5, y: -1 },
                ]
                break;
        }
        return unit;
    }
    function getNext() {
        let n = Math.floor(Math.random() * 10) % 5 + 1;
        for (let i = 1; i <= 5; i++) {
            document.getElementsByClassName("shape" + i)[0].style.display = "none";
        }
        document.getElementsByClassName("shape" + n)[0].style.display = "block";
        return n;
    }
    function move() {
        let flag = 0;
        for (let i = 0; i < 4; i++) {
            let x = unit[i].x;
            let y = unit[i].y + 1;
            if (y < 0) {
                continue;
            }
            if (y >= 15) {
                flag = 1;
                break;
            }
            if (blocks[y][x].flag != 0) {
                flag = 1;
                break;
            }
        }
        if (flag) {
            for (let i = 0; i < 4; i++) {
                let x = unit[i].x;
                let y = unit[i].y;
                if (y < 0) {
                    flag = 2;
                } else {
                    blocks[y][x].flag = 1;
                }
            }
            if (flag == 2) {
                //游戏结束
                gameOver();
                return;
            }
            eliminate();//消除同行
            unit = getUnit(next);
            unitCode = next;
            next = getNext();


        } else {
            for (let i = 0; i < 4; i++) {
                unit[i].y++;
            }
        }
        display();
    }
    function moveSide(dir) {//横向移动 dir: -1 1
        let flag = 0;
        for (let i = 0; i < 4; i++) {
            let x = unit[i].x + dir;
            let y = unit[i].y;
            if (x >= 10 || x < 0) {
                flag = 1;
                break;
            }
            if (y >= 0) {
                if (blocks[y][x].flag != 0) {
                    flag = 1;
                    break;
                }
            }
        }
        if (flag) {
            return;
        } else {
            for (let i = 0; i < 4; i++) {
                unit[i].x += dir;
            }
        }
        display();
    }
    function rotate() {
        let backUpUnit = [
            { x: unit[0].x, y: unit[0].y },
            { x: unit[1].x, y: unit[1].y },
            { x: unit[2].x, y: unit[2].y },
            { x: unit[3].x, y: unit[3].y }
        ]
        let backUpUnitCode = unitCode;
        switch (unitCode) {
            case 1:
                unitCode = 12;
                unit[3].x -= 2;
                unit[3].y--;
                unit[2].y--;
                break;
            case 12:
                unitCode = 1;
                unit[3].x += 2;
                unit[3].y++;
                unit[2].y++;
                break;
            case 2:
                unitCode = 22;
                unit[1].x++;
                unit[1].y++;
                break;
            case 22:
                unitCode = 23;
                unit[1].x--;
                unit[1].y--;
                unit[0].y += 2;
                break;
            case 23:
                unitCode = 24;
                unit[0].y -= 2;
                unit[3].y++;
                unit[3].x--;
                break;
            case 24:
                unitCode = 2;
                unit[3].y--;
                unit[3].x++;
                break;
            case 3:
                unitCode = 32;
                unit[0].x += 2;
                unit[1].y++;
                unit[1].x++;
                unit[3].x--;
                unit[3].y--;
                break;
            case 32:
                unitCode = 33;
                unit[0].x -= 2;
                unit[1].y--;
                unit[1].x--;
                unit[3].x++;
                unit[3].y++;

                unit[0].x += 2;
                unit[0].y += 2;
                break;

            case 33:
                unitCode = 34;
                unit[0].x -= 2;
                unit[0].y -= 2;

                unit[0].y += 2;
                unit[1].y++;
                unit[1].x--;
                unit[3].x++;
                unit[3].y--;
                break;
            case 34:
                unitCode = 3;
                unit[0].y -= 2;
                unit[1].y--;
                unit[1].x++;
                unit[3].x--;
                unit[3].y++;
                break;
            case 4:
                return;
                break;
            case 5:
                unitCode = 52;
                unit[3].x--; unit[3].y--;
                unit[0].x += 2;
                unit[0].y += 2;
                unit[1].y++;
                unit[1].x++;
                break;
            case 52:
                unitCode = 5;
                unit[3].x++; unit[3].y++;
                unit[0].x -= 2;
                unit[0].y -= 2;
                unit[1].y--;
                unit[1].x--;
                break;
        }
        try {
            display();
        } catch (e) {
            unit = backUpUnit;
            unitCode = backUpUnitCode;

            display();
        }


    }
    function display() {
        for (let i = 0; i < 15; i++) {
            for (let k = 0; k < 10; k++) {
                blocks[i][k].style.backgroundColor = "grey";
                blocks[i][k].innerHTML = "";
                if (blocks[i][k].flag != 0) {
                    blocks[i][k].style.backgroundColor = "green";
                }
            }
        }
        for (let i = 0; i < 4; i++) {
            if (unit[i].y >= 0 && unit[i].y < 15) {
                let x = unit[i].x, y = unit[i].y;
                blocks[y][x].style.backgroundColor = "red";
                // blocks[y][x].innerHTML = i;
            }
        }
    }
    function addScore() {
        score += 10;
        document.getElementsByClassName("score")[0].getElementsByClassName("databox")[0].innerText = score;
        if (score > best) {
            best = score;
            document.getElementsByClassName("best")[0].getElementsByClassName("databox")[0].innerText = best;
            localStorage.best = best;
        }
    }
    function eliminate() {//消除同行
        for (let i = 0; i < 15; i++) {
            let flag = 1;
            for (let k = 0; k < 10; k++) {
                if (blocks[i][k].flag == 0) {
                    flag = 0;
                }
            }
            if (flag) {
                addScore();
                for (let k = 0; k < 10; k++) {
                    blocks[i][k].flag = 0
                }
                //向上交换把空行移到顶部
                for (let y = i; y > 0; y--) {
                    for (let x = 0; x < 10; x++) {
                        let t = blocks[y][x].flag;
                        blocks[y][x].flag = blocks[y - 1][x].flag;
                        blocks[y - 1][x].flag = t;
                    }
                }
            }
        }
    }
    function gameOver() {
        clearInterval(time);
        document.getElementById("start").innerText = "START";
        isGameOver = 1;
    }
    function reset() {
        document.getElementsByClassName("speed")[0].getElementsByClassName("databox")[0].innerText = speed;
        for (let i = 0; i < 15; i++) {
            for (let k = 0; k < 10; k++) {
                blocks[i][k].flag = 0;
                blocks[i][k].style.backgroundColor = "grey";
            }
        }
        score = 0;
        unit = null;
        next = null;
        unitCode = null;
        if (localStorage.best) {
            best = localStorage.best;
        }
    }
    let start = document.getElementById("start")
    start.onclick = function (e) {
        let div = e.target;
        if (div.innerText == "START") {
            if (isGameOver) {
                reset();
                score = 0;
                best = 0;
                next = getNext();
                unit = getUnit(next);
                unitCode = next;
                next = getNext();
                time = setInterval(move, speed);
                isGameOver = 0;
            } else {
            }
            div.innerText = "STOP";
        } else {
            div.innerText = "START";
        }
    }
    window.onkeydown = function (e) {
        try {
            if (e.key == 'w' || e.key == 'W') {
                rotate();
            }
            if (e.key == 's' || e.key == 'S') {
                move();
            }
            if (e.key == 'a' || e.key == 'A') {
                moveSide(-1)
            }
            if (e.key == 'd' || e.key == 'D') {
                moveSide(1)
            }
        } catch (e) {
            console.log("放心啥事都没有");
        }

    }
    const height = 15, width = 10;//禁止修改
    const blocks = getBlocks();
    let speed = 500, score = 0, best = 0;
    let next;//下一个方块
    let unit;//当前正在移动的方块
    let unitCode;//当前正在移动的方块代码
    let time;//timeInterval
    let isGameOver = 1;
    reset();
</script>

</html>